package com.anjufang.utils;

import org.apache.commons.lang.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * <p>日期工具类</p>
 * @author joel
 * Date:2017年3月9日上午10:32:56 
 * @version
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {

	private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd",
			"yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyyMMddHHmmss", "yyyyMMddHHmmssSSS", "yyyyMMdd", "yyyyMMddHHmm" };

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd）
	 */
	public static String getDate() {
		return getDate("yyyy-MM-dd");
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String getDate(String pattern) {
		return DateFormatUtils.format(new Date(), pattern);
	}

	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate = null;
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString());
		} else {
			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
		}
		return formatDate;
	}
	
	public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }
	
	/**
	 * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String formatDateTime(Date date) {
		return formatDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前时间字符串 格式（HH:mm:ss）
	 */
	public static String getTime() {
		return formatDate(new Date(), "HH:mm:ss");
	}

	/**
	 * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String getDateTime() {
		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前年份字符串 格式（yyyy）
	 */
	public static String getYear() {
		return formatDate(new Date(), "yyyy");
	}

	/**
	 * 得到当前月份字符串 格式（MM）
	 */
	public static String getMonth() {
		return formatDate(new Date(), "MM");
	}

	/**
	 * 得到当天字符串 格式（dd）
	 */
	public static String getDay() {
		return formatDate(new Date(), "dd");
	}

	/**
	 * 得到当前星期字符串 格式（E）星期几
	 */
	public static String getWeek() {
		return formatDate(new Date(), "E");
	}

	/**
	 * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
	 * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyyMMdd" }
	 * @param parsePatterns2 
	 */
	public static Date parseDate(Object str) {
		if (str == null) {
			return null;
		}
		try {
			return parseDate(str.toString(), parsePatterns);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取过去的天数
	 * 
	 * @param date
	 * @return
	 */
	public static long pastDays(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (24 * 60 * 60 * 1000);
	}

	/**
	 * 获取过去的小时
	 * 
	 * @param date
	 * @return
	 */
	public static long pastHour(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (60 * 60 * 1000);
	}

	/**
	 * 获取过去的分钟
	 * 
	 * @param date
	 * @return
	 */
	public static long pastMinutes(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (60 * 1000);
	}
	/**
	 * 获取过去的毫秒
	 * @param date
	 * @return
	 */
	public static long pastMills(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t;
	}

	/**
	 * 转换为时间（天,时:分:秒.毫秒）
	 * 
	 * @param timeMillis
	 * @return
	 */
	public static String formatDateTime(long timeMillis) {
		long day = timeMillis / (24 * 60 * 60 * 1000);
		long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
		long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
		return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
	}
	/**
	 * 时间戳转日期
	 * @param time(秒)
	 * @return yyyy-MM-dd
	 */
	public static String timeToDate(String time) {
		
		String result = "";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        long lt = new Long(time + "000");
        Date date = new Date(lt);
        result = simpleDateFormat.format(date);
        return result;
	}
	
	/**
	 * 获取某一天的开始时间（0点）
	 * 
	 * @param date
	 * @return
	 */
	public static Date getDateStart(Date date) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 00:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	/**
	 * 获取某一天的开始时间（0点）
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateStartStr(Date date) {
		if (date == null) {
			return null;
		}
		return formatDate(date, "yyyy-MM-dd") + " 00:00:00";
	}

	/**
	 * 获取某一天的结束时间(23:59)
	 * 
	 * @param date
	 * @return
	 */
	public static Date getDateEnd(Date date) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 23:59:59");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	/**
	 * 获取某一天的结束时间(23:59)
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateEndStr(Date date) {
		if (date == null) {
			return null;
		}
		return formatDate(date, "yyyy-MM-dd")  + " 23:59:59";
	}

	/**
	 * 比较两个日期时间的大小,反回1表示preDateStr > nextDateStr，0就相等，-1为小于
	 * 
	 * @author: weihuang.peng
	 * @param preDateStr
	 * @param nextDateStr
	 * @return result
	 */
	public static int compareDate(Object preDateStr, Object nextDateStr) {
		int result = 0;
		Date preDate = parseDate(preDateStr);
		Date nextDate = parseDate(nextDateStr);
		try {
			result = preDate.compareTo(nextDate);
		} catch (Exception e) {
			result = 0;
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 获取某一天的前几天或者后几天，根据数字符号决定天数
	 * 
	 * @author: weihuang.peng
	 * @param date
	 * @param days
	 * @return
	 */
	public static String getPastDayStr(Object dateObj, int days) {
		Date date = parseDate(dateObj);
		long time = date.getTime() + days * (long) (24 * 60 * 60 * 1000);
		return formatDate(new Date(time));
	}
	
	/**
	 * 获取某一天的前几天或者后几天，根据数字符号决定天数
	 * 
	 * @author: weihuang.peng
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date getPastDay(Object dateObj, int days) {
		Date date = parseDate(dateObj);
		long time = date.getTime() + days * (long) (24 * 60 * 60 * 1000);
		return new Date(time);
	}

	/**
	 * preDateStr - nextDateStr 返回秒数
	 * 
	 * @author: huiyang.yu
	 * @param preDateStr
	 * @param nextDateStr
	 * @return
	 */
	public static long getSubactDate(Object preDateStr, Object nextDateStr) {
		Date preDate = parseDate(preDateStr);
		Date nextDate = parseDate(nextDateStr);
		long result = (preDate.getTime() - nextDate.getTime()) / 1000L;
		return result;
	}

	/**
	 * 返回过去的天数： preDateStr - nextDateStr
	 * 
	 * @author: weihuang.peng
	 * @param preDateStr
	 * @param nextDateStr
	 * @return
	 */
	public static long getDifferDate(Object preDateStr, Object nextDateStr) {
		return getSubactDate(preDateStr, nextDateStr) / (60 * 60 * 24L);
	}

	/**
	 * 传入日期时间与当前系统日期时间的比较, 若日期相同，则根据时分秒来返回 , 否则返回具体日期
	 * 
	 * @author: huiyang.yu
	 * @param updateDate
	 *            传入日期
	 * @param updateTime
	 *            传入时间
	 * @return 日期或者 xx小时前||xx分钟前||xx秒前
	 */
	public static String getNewUpdateDateString(String updateDate, String updateTime) {
		String result = updateDate;
		long time = 0;
		if (updateDate.equals(DateUtils.getDate())) {
			time = DateUtils.getSubactDate(DateUtils.getDateTime(), updateDate + " " + updateTime);
			if (time >= 3600) {
				result = time / 3600 + "小时前";
			} else if (time >= 60) {
				result = time / 60 + "分钟前";
			} else if (time >= 1) {
				result = time + "秒前";
			} else {
				result = "刚刚";
			}
		} else if (result.length() >= 10) {
			result = result.substring(5);
		}
		return result;
	}
	
	/**
	 * 两个日期相关天数
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static long getDateDiff(String startDate, String endDate) {
		long diff = 0;
		try {
			Date date1 = new SimpleDateFormat("yyyy-MM-dd").parse(startDate);
			Date date2 = new SimpleDateFormat("yyyy-MM-dd").parse(endDate);

			diff = (date1.getTime() - date2.getTime()) / (24 * 60 * 60 * 1000) > 0 ? (date1.getTime() - date2.getTime())
					/ (24 * 60 * 60 * 1000)
					: (date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000);
		} catch (ParseException e) {
		}
		return diff;
	}
	
	/**
	 * 日期距现在天数
	 * 
	 * @param date
	 * @return
	 */
	public static long dateDiff(Date date) {
		Date nowDate = new Date(); // 当前时间
		long diff = (nowDate.getTime() - date.getTime()) / (24 * 60 * 60 * 1000) > 0 
				? (nowDate.getTime() - date.getTime()) / (24 * 60 * 60 * 1000) 
				: (date.getTime() - nowDate.getTime()) / (24 * 60 * 60 * 1000);
		return diff;
	}
	
	/**
	 * 时间戳转日期
	 * @param mills
	 * @return
	 */
	public static String stampToDate(Long mills) {
		
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date(mills);
		return format.format(date);
	}
	
	/**
	 * 时间戳转日期,自定义格式
	 * @param mills
	 * @return
	 */
	public static String stampToDate(Long mills,String formatStr) {
		
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		Date date = new Date(mills);
		return format.format(date);
	}
	
	/**
	 * 获取当前时间戳，精确到秒
	 * @return
	 */
	public static long getCurrentDateMillis() {
		
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
			Date date = simpleDateFormat.parse(getDate("yyyy-MM-dd HH:mm:ss"));
			Long millis = date.getTime() / 1000;
			return millis;
		} catch (ParseException e) {
			e.printStackTrace();
			return 0L;
		}
	}
	
	/**
	 * 获取上个月开始与结束时间
	 * @param past
	 * @return
	 */
	public static String[] getMonths(int past) {
		Calendar c=Calendar.getInstance();
		c.add(Calendar.MONTH, past);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
		int lastMonthMaxDay=c.getActualMaximum(Calendar.DAY_OF_MONTH);
		c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), lastMonthMaxDay, 23, 59, 59);
		//按格式输出
		String gtimeEnd = sdf.format(c.getTime()); //上月最后一天
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-01  00:00:00");
		String gtimeStart = sdf2.format(c.getTime()); //上月第一天
		String[] dates = {gtimeStart, gtimeEnd};
		return dates;
	}
	
	/**
	 * 获取本周的开始时间
	 * @return
	 */
	public static Date getBeginDayOfWeek() {
		Date date = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
		dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);
		return getDateStart(cal.getTime());
	}
	
	/**
	 * 获取本周的开始时间,返回string
	 * @return 
	 */
	public static String getBeginDayOfWeekStr() {
		Date date = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
		dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);
		return getDateStartStr(cal.getTime());
	}
	
	/**
	 * 获取本周的结束时间
	 * @return
	 */
	public static Date getEndDayOfWeek() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return getDateEnd(weekEndSta);
	}
	
	/**
	 * 获取本周的结束时间,返回String
	 * @return
	 */
	public static String getEndDayOfWeekStr() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return getDateEndStr(weekEndSta);
	}
	
	/**
	 * 上周开始时间 yyyy-MM-dd 00:00:00
	 * @return
	 */
	public static String laskWeekBegin() {
		Date thisMon = getBeginDayOfWeek();
		Date lastMon = getPastDay(thisMon, -7);
		return getDateStartStr(lastMon);
	}
	
	/**
	 * 上周结束时间 yyyy-MM-dd 23:59:59
	 * @return
	 */
	public static String laskWeekEnd() {
		Date thisSun = getEndDayOfWeek();
		Date lastSun = getPastDay(thisSun, -7);
		return getDateEndStr(lastSun);
	}
	
	/**
	 * 根据指定时间计算距离现在的秒数
	 * @param dataObj
	 * @return
	 */
	public static int caclSecondByData(Object dataObj) {
		String nowDate = getDate("yyyy-MM-dd HH:mm:ss");
		long second = getSubactDate(dataObj, nowDate);
		return (int) second;
	}
	
	/**
	 * 把日期往后增加n天.正数往后推,负数往前移动 
	 * @param n
	 * @return 
	 */
	public static Date getPastDay(Date date ,int n) {
		// 为null就取当前时间
	  	if (date == null) {
			date = new Date();
		}
	    Calendar calendar  =   Calendar.getInstance();
	 
	    calendar.setTime(date); //需要将date数据转移到Calender对象中操作
	    calendar.add(calendar.DATE, n);//把日期往后增加n天.正数往后推,负数往前移动 
	    return calendar.getTime();   //这个时间就是日期往后推一天的结果
	}
	/**
	 * 把日期往后增加n小时.正数往后推,负数往前移动 
	 * @param date
	 * @param n
	 * @return
	 */
	public static Date getPastHour(Date date ,int n) {
		// 为null就取当前时间
	  	if (date == null) {
			date = new Date();
		}
	    Calendar calendar  =   Calendar.getInstance();
	    calendar.setTime(date); //需要将date数据转移到Calender对象中操作
	    calendar.add(calendar.HOUR, n);
	    return calendar.getTime();   //这个时间就是日期往后推一天的结果
	}
	
	/**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1,Date date2)
    {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        return days;
    }
    
    /**
     * 两个日期相差的分钟数
     * @param datePre
     * @param dateAter
     * @return
     */
    public static long differentMin(Date datePre, Date dateAter) {
    	long times = (dateAter.getTime() - datePre.getTime()) / (1000 * 60);
    	return times;
    }
    
    
    public final static String FORMAT_STRING = "yyyy-MM-dd HH:mm:ss";

    public final static String[] REPLACE_STRING = new String[]{"GMT+0800", "GMT+08:00"};

    public final static String SPLIT_STRING = "(中国标准时间)";
    /**
     * Mon Sep 02 2019 00:00:00 GMT+0800 (中国标准时间)字符串转成date
     * @param dateString
     * @return
     */
    public static Date str2Date(String dateString) {
        try {
            dateString = dateString.split(Pattern.quote(SPLIT_STRING))[0].replace(REPLACE_STRING[0], REPLACE_STRING[1]);
            SimpleDateFormat sf1 = new SimpleDateFormat("E MMM dd yyyy HH:mm:ss z", Locale.US);
            Date date = sf1.parse(dateString);
            return date;
        } catch (Exception e) {
            throw new RuntimeException("时间转化格式错误" + "[dateString=" + dateString + "]" + "[FORMAT_STRING=" + FORMAT_STRING + "]");
        }
    }
    
    /**
     * 获取hour个小时后的Unix时间戳（普通时间戳/1000）
     * @param hour
     * @return
     */
    public static long getUnixStamp(int hour) {
    	long currentTime = System.currentTimeMillis() / 1000;
    	long time = hour * 60 * 60;
    	return currentTime + time;
    }
    
	public static void main(String[] args) {
		
		Date date = DateUtils.parseDate("2020-09-17 23:59:59");
		
		long day = DateUtils.pastDays(DateUtils.getDateStart(date));
		System.out.println(day);
	}
}
